//
//  ServerBlue.m
//  blue_classic_plus
//
//  Created by os on 1/19/24.
//

#import "ServerBlue.h"

#define ServerStateType @"serverState"

@implementation ServerBlue

// 返回的给flutter的标准结构
- (void) toFlutterType:(NSString *)type code:(NSNumber *)code msg:(NSString *)msg{
    
    NSMutableDictionary * dic = [NSMutableDictionary dictionary];
    dic[@"type"] = type;
    if (code != nil) {
        dic[@"code"] = code;
    }
    if (msg != nil) {
        dic[@"msg"] = msg;
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        self.sink(dic);
    });
    
}


//初始化方法
- (instancetype)initWithSink:(FlutterEventSink)sink uuid:(NSString *)uuid name:(nonnull NSString *)name {
    self = [super init];
    if (self) {
        //创建一个CBPeripheralManager对象，设置代理和队列
        self.uuid = uuid;
        self.name = name;
        self.peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:self queue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)];
        
        self.sink = sink;
    }
    return self;
}

//开始广播的方法
- (void)startAdvertising:(NSDictionary *)advertisementData {
    //判断外设管理器的状态是否为开启
    if (self.peripheralManager.state == CBManagerStatePoweredOn) {
        //创建一个CBUUID对象，表示服务的UUID
        CBUUID *serviceUUID = [CBUUID UUIDWithString:self.uuid];
        //创建一个CBMutableService对象，设置UUID和是否为主服务
        self.service = [[CBMutableService alloc] initWithType:serviceUUID primary:YES];
        //创建一个CBUUID对象，表示特征的UUID
        CBUUID *characteristicUUID = [CBUUID UUIDWithString:self.uuid];
        //创建一个CBMutableCharacteristic对象，设置UUID，属性，值，权限等
        self.characteristic = [[CBMutableCharacteristic alloc] initWithType:characteristicUUID properties:CBCharacteristicPropertyRead | CBCharacteristicPropertyWrite|CBCharacteristicPropertyNotify value:nil permissions:CBAttributePermissionsReadable | CBAttributePermissionsWriteable];
        //将特征添加到服务中
        self.service.characteristics = @[self.characteristic];
        //将服务添加到外设管理器中
        [self.peripheralManager addService:self.service];
        //开始广播，传入广播数据字典
        [self.peripheralManager startAdvertising:advertisementData];
    }
}

//停止广播的方法
- (void)stopServer {
    //判断外设管理器是否正在广播
    if (self.peripheralManager.isAdvertising) {
        //停止广播
        [self.peripheralManager stopAdvertising];
    }
    
    // 移除所有的服务，并不代表会立即断开
    [self.peripheralManager removeAllServices];
    self.serverListening = false;
    
}

//实现CBPeripheralManagerDelegate协议的方法

//当外设管理器的状态更新时，会调用此方法
- (void)peripheralManagerDidUpdateState:(CBPeripheralManager *)peripheral {
    if (peripheral.state == CBManagerStatePoweredOn) {
        NSDictionary *advertisementData = @{CBAdvertisementDataServiceUUIDsKey: @[[CBUUID UUIDWithString:self.uuid]],
                                           CBAdvertisementDataLocalNameKey: self.name};
        [self startAdvertising:advertisementData];
    } else {
        [self toFlutterType:ServerStateType code:@(peripheral.state) msg:@"蓝牙状态不是CBManagerStatePoweredOn"];
    }
    
}

//当外设管理器添加服务时，会调用此方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral didAddService:(CBService *)service error:(NSError *)error {
    //判断是否有错误
    if (error) {
        [self toFlutterType:ServerStateType code:@(6) msg:@"蓝牙服务端添加服务出错"];
    } else {
        //打印成功信息
        NSLog(@"Added service: %@", service.UUID);
    }
}

//当外设管理器开始广播时，会调用此方法
- (void)peripheralManagerDidStartAdvertising:(CBPeripheralManager *)peripheral error:(NSError *)error {
    //判断是否有错误
    if (error) {
        [self toFlutterType:ServerStateType code:@(6) msg:@"蓝牙服务端广播出错"];
        self.serverListening = false;
    } else {
        //打印成功信息
        [self toFlutterType:ServerStateType code:@(7) msg:@"蓝牙服务端开启监听中"];
        self.serverListening = true;
    }
}

//当外设管理器收到中心设备的读请求时，会调用此方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request {
    //判断请求的特征是否为我们的特征
    if ([request.characteristic.UUID isEqual:self.characteristic.UUID]) {
        //如果是，设置请求的值为我们的特征的值
        request.value = self.characteristic.value;
        //响应请求，结果为成功
        [peripheral respondToRequest:request withResult:CBATTErrorSuccess];
    } else {
        //如果不是，响应请求，结果为请求的特征不可读
        [peripheral respondToRequest:request withResult:CBATTErrorReadNotPermitted];
    }
}

//当外设管理器收到中心设备的写请求时，会调用此方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral didReceiveWriteRequests:(NSArray *)requests {
    //遍历所有的请求
    for (CBATTRequest *request in requests) {
        //判断请求的特征是否为我们的特征
        if ([request.characteristic.UUID isEqual:self.characteristic.UUID]) {
            //如果是，设置我们的特征的值为请求的值
            self.characteristic.value = request.value;
            //响应请求，结果为成功
            [peripheral respondToRequest:request withResult:CBATTErrorSuccess];
        } else {
            //如果不是，响应请求，结果为请求的特征不可写
            [peripheral respondToRequest:request withResult:CBATTErrorWriteNotPermitted];
            
        }
    }
}

//当外设管理器的特征被订阅时，会调用此方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didSubscribeToCharacteristic:(CBCharacteristic *)characteristic {
    ///有外设连接进来
    
    [self toFlutterType:ServerStateType code:@(8) msg:@"客户端连接成功"];
}

//当外设管理器的特征被取消订阅时，会调用此方法
- (void)peripheralManager:(CBPeripheralManager *)peripheral central:(CBCentral *)central didUnsubscribeFromCharacteristic:(CBCharacteristic *)characteristic {
    //打印取消订阅信息
    [self toFlutterType:ServerStateType code:@(10) msg:@"客户端断开连接"];
}


//定义一个广播方法，传入一个数据对象
- (void)broadcastData:(NSData *)data {
    //判断外设管理器是否正在广播
    //判断是否有中心设备订阅了我们的特征
    if (self.characteristic == nil) return;
    if (self.peripheralManager == nil) return;
    
    if (self.characteristic.subscribedCentrals.count > 0) {
        //遍历所有的订阅中心设备
        dispatch_async(dispatch_get_main_queue(), ^{
            // 在主线程执行的代码
            [self.peripheralManager updateValue:data forCharacteristic:self.characteristic onSubscribedCentrals:self.characteristic.subscribedCentrals];
        });
    }
}

@end
